package com.hsnn.medstgmini.base.std.dao.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.hsnn.medstgmini.base.dict.dao.DicPharDao;
import com.hsnn.medstgmini.base.dict.model.DicDrugform;
import com.hsnn.medstgmini.base.dict.model.DicDrugmaterial;
import com.hsnn.medstgmini.base.dict.model.DicDrugspec;
import com.hsnn.medstgmini.base.dict.model.DicSys;
import com.hsnn.medstgmini.base.std.dao.StdDrugInfoDao;
import com.hsnn.medstgmini.base.std.model.StdCompinfo;
import com.hsnn.medstgmini.base.std.model.StdDrugInfo;
import com.hsnn.medstgmini.base.std.model.StdDruginfoDetail;
import com.hsnn.medstgmini.base.std.model.StdDruginfoDetailLog;
import com.hsnn.medstgmini.base.std.model.StdDruginfoLog;
import com.hsnn.medstgmini.base.std.model.form.StdDrugInfoForm;
import com.hsnn.medstgmini.dao.HibernateSqlUtil;
import com.hsnn.medstgmini.util.Pagination;
import com.hsnn.medstgmini.util.ParseDate;
import com.hsnn.medstgmini.util.PinYin;

@Repository("stdDrugInfoDao")
public class StdDrugInfoDaoImpl implements StdDrugInfoDao {

	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	@Autowired
	private DicPharDao dicPharDao;
	@Autowired
	private HibernateSqlUtil dao;
	
	private Session getSession() {
		Session session = sessionFactory.getCurrentSession();
		return session;
	}

	@Override
	public Pagination getAllByPage(Pagination page) {
		Criteria criteria = getSession().createCriteria(StdDrugInfo.class);
		Map<String, String> conditions = page.getConditions();
		if (null != conditions && conditions.size() > 0) {
			if (null != conditions.get("drugCode")
					&& !"".equals(conditions.get("drugCode").trim())) {
				criteria.add(Restrictions.eq("drugCode",
						conditions.get("drugCode").trim()));
			}
			if (null != conditions.get("drugName")
					&& !"".equals(conditions.get("drugName").trim())) {
				criteria.add(Restrictions.like("drugName",
						conditions.get("drugName").trim(), MatchMode.ANYWHERE));
			}
			
			if(StringUtils.isNotBlank(conditions.get("drugId"))){
				criteria.add(Restrictions.not(Restrictions.in("drugId", conditions.get("drugId").trim().split(","))));
			}
			if (null != conditions.get("drugNameSpel")
					&& !"".equals(conditions.get("drugNameSpel").trim())) {
				criteria.add(Restrictions.like("drugNameSpel",
						conditions.get("drugNameSpel").trim().toUpperCase(), MatchMode.ANYWHERE));
			}
			if (null != conditions.get("formId")
					&& !"".equals(conditions.get("formId").trim())) {
				criteria.add(Restrictions.eq("drugform.formId",
						conditions.get("formId").trim()));
			}
			if (null != conditions.get("specId")
					&& !"".equals(conditions.get("specId").trim())) {
				criteria.add(Restrictions.eq("drugspec.specId",
						conditions.get("specId").trim()));
			}
			if (null != conditions.get("prodPompId")
					&& !"".equals(conditions.get("prodPompId").trim())) {
				criteria.add(Restrictions.eq("compinfo.compId",
						conditions.get("prodPompId").trim()));
			}

		}
		Long totalCount = (Long) criteria.setProjection(Projections.rowCount())
				.uniqueResult();
		criteria.setProjection(null);
		criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		criteria.setFirstResult((page.getPage() - 1) * page.getMaxResults());
		criteria.setMaxResults(page.getMaxResults());
		List<StdDrugInfo> records = criteria.list();

		page.setRecords(totalCount);

		page.setTotal(new Long(totalCount % page.getMaxResults() == 0 ? totalCount
				/ page.getMaxResults() : totalCount / page.getMaxResults() + 1)
				.intValue());
		page.setRows(records);
		return page;
	}

	public String addData(StdDrugInfoForm form) {
		StdDrugInfo df = new StdDrugInfo();
		df.setDrugId(UUID.randomUUID().toString());
		df.setDrugCode(form.getDrugCode());
		df.setDrugName(form.getDrugName());
		df.setDrugNameSpel(PinYin.getPinYinHeadChar(form.getDrugName()));
		df.setDrugNameEng(form.getDrugNameEng());
		df.setBusName(form.getBusName());
		df.setDrugform(getDrugForm(form.getFormId()));
		df.setDrugspec(getDrugSpec(form.getSpecId()));
		df.setFactor(form.getFactor());
		df.setUnit(form.getUnit());
		df.setCompinfo(getStdCompinfo(form.getProdPompId()));
		df.setDrugmaterial(getDicDrugmaterial(form.getMaterialId()));
		df.setApprovalCode(form.getApprovalCode());
		df.setApprovalDate(form.getApprovalDate() == null ? null : ParseDate
				.fromFullFormat(form.getApprovalDate()));
		df.setStatus(Short.valueOf("1"));
		df.setUpdDatetime(new Date());
		df.setUpdUser(form.getUpdUser());
		df.setHistoryDrugCode(form.getHistoryDrugCode());
		df.setMergeStatus(Short.valueOf("0"));
		StdDruginfoDetail dfd = new StdDruginfoDetail();
		dfd.setDrugId(df.getDrugId());
		dfd.setDrugAttr(form.getDrugAttr()==null?null:form.getDrugAttr().trim().equals("")?null:Short.valueOf(form.getDrugAttr()));
		dfd.setDrugIndex(form.getDrugIndex() == null ? null :  Integer
				.valueOf(form.getDrugIndex()));
		dfd.setPhar(dicPharDao.getDicPharById(form.getPharId()));
		dfd.setPatternType(form.getPatternType() == null ? null :"".equals(form.getPatternType())?null: Short
				.valueOf(form.getPatternType()));
		dfd.setDrugSource(form.getDrugSource() == null ? null :"".equals(form.getDrugSource())?null: Short
				.valueOf(form.getDrugSource()));
		dfd.setIsLowprice(form.getIsLowprice() == null ? null :"".equals(form.getDrugSource())?null: Short
				.valueOf(form.getIsLowprice()));
		dfd.setIsAgriculture(form.getIsAgriculture() == null ? null :"".equals(form.getIsAgriculture())?null: Short
				.valueOf(form.getIsAgriculture()));
		dfd.setIsHealthcare(form.getIsHealthcare() == null ? null :"".equals(form.getIsHealthcare())?null: Short
				.valueOf(form.getIsHealthcare()));
		dfd.setDrugStdCode(form.getDrugStdCode());
		dfd.setDrugStdcdRemark(form.getDrugStdcdRemark());
		dfd.setRemark(form.getRemark());
		dfd.setUpdDatetime(form.getUpdDatetime() == null ? null : ParseDate
				.fromFullFormat(form.getUpdDatetime()));
		dfd.setUpdUser(form.getUpdUser());
		try {
			getSession().save(df);
			getSession().save(dfd);
			getSession().flush();
			writeLog(df, dfd);
			return "success";
		} catch (Exception e) {
			e.printStackTrace();
			return "faile";
		}
	}

	public String editInfo(StdDrugInfoForm form) {
		StdDrugInfo df = getDrugInfo(form.getDrugId());
		df.setDrugCode(form.getDrugCode());
		df.setDrugName(form.getDrugName());
		df.setDrugNameSpel(PinYin.getPinYinHeadChar(form.getDrugName()));
		df.setDrugNameEng(form.getDrugNameEng());
		df.setBusName(form.getBusName());
		df.setDrugform(getDrugForm(form.getFormId()));
		df.setDrugspec(getDrugSpec(form.getSpecId()));
		df.setFactor(form.getFactor());
		df.setUnit(form.getUnit());
		df.setCompinfo(getStdCompinfo(form.getProdPompId()));
		df.setDrugmaterial(getDicDrugmaterial(form.getMaterialId()));
		df.setApprovalCode(form.getApprovalCode());
		df.setApprovalDate(form.getApprovalDate() == null ? null : ParseDate
				.fromFullFormat(form.getApprovalDate()));
		// df.setStatus(Short.valueOf("1"));
		df.setUpdDatetime(new Date());
		df.setUpdUser(form.getUpdUser());
		df.setHistoryDrugCode(form.getHistoryDrugCode());
		// df.setMergeStatus(Short.valueOf("0"));
		StdDruginfoDetail dfd = getDrugInfoDetail(form.getDrugId());
		dfd.setDrugAttr(form.getDrugAttr()==null?null:form.getDrugAttr().trim().equals("")?null:Short.valueOf(form.getDrugAttr()));
		dfd.setDrugIndex(form.getDrugIndex() == null ? null :form.getDrugIndex().equals("")?null: Integer
				.valueOf(form.getDrugIndex()));
		dfd.setPhar(dicPharDao.getDicPharById(form.getPharId()));
		dfd.setPatternType(form.getPatternType() == null ? null :form.getPatternType().trim().equals("")?null: Short
				.valueOf(form.getPatternType()));
		dfd.setDrugSource(form.getDrugSource() == null ? null :form.getDrugSource().trim().equals("")?null: Short
				.valueOf(form.getDrugSource()));
		dfd.setIsLowprice(form.getIsLowprice() == null ? null :"".equals(form.getIsLowprice().trim())?null: Short
				.valueOf(form.getIsLowprice()));
		dfd.setIsAgriculture(form.getIsAgriculture() == null ? null :"".equals(form.getIsAgriculture().trim())?null: Short
				.valueOf(form.getIsAgriculture()));
		dfd.setIsHealthcare(form.getIsHealthcare() == null ? null :"".equals(form.getIsHealthcare().trim())?null: Short
				.valueOf(form.getIsHealthcare()));
		dfd.setDrugStdCode(form.getDrugStdCode());
		dfd.setDrugStdcdRemark(form.getDrugStdcdRemark());
		dfd.setRemark(form.getRemark());
		dfd.setUpdDatetime(form.getUpdDatetime() == null ? null : ParseDate
				.fromFullFormat(form.getUpdDatetime()));
		dfd.setUpdUser(form.getUpdUser());
		try {
			getSession().update(df);
			getSession().update(dfd);
			getSession().flush();
			writeLog(df, dfd);
			return "success";
		} catch (Exception e) {
			e.printStackTrace();
			return "faile";
		}
	}

	public String startOrStop(String id, Short statu,String userId) {
		StdDrugInfo data = getDrugInfo(id);
		data.setStatus(statu);
		data.setUpdUser(userId);
		data.setUpdDatetime(new Date());
		try {
			getSession().update(data);
			getSession().flush();
			writeLog(data, getDrugInfoDetail(id));
			return "success";
		} catch (Exception e) {
			e.printStackTrace();
			return "failed";
		}
	}

	/**
	 * 批量处理启用停用
	 */
	public String batchStartOrStop(List<StdDrugInfo> list) {
		if (list != null && list.size() > 0) {
			for (StdDrugInfo drugInfo : list) {
				if (drugInfo != null && drugInfo.getDrugId() != null
						&& drugInfo.getStatus() != null) {
					StdDrugInfo data = getDrugInfo(drugInfo.getDrugId());
					data.setStatus(drugInfo.getStatus());
					data.setUpdUser(drugInfo.getUpdUser());
					data.setUpdDatetime(new Date());
					try {
						getSession().update(data);
						getSession().flush();
						writeLog(getDrugInfo(drugInfo.getDrugId()),
								getDrugInfoDetail(drugInfo.getDrugId()));

					} catch (Exception e) {
						e.printStackTrace();
						return "failed";
					}

				}
			}
			return "success";
		}
		return "failed";
	}

	public StdDrugInfo getDrugInfo(String id) {
		StdDrugInfo data = (StdDrugInfo) getSession()
				.get(StdDrugInfo.class, id);
		return data;
	}
	public StdDrugInfo getDrugInfoByCode(String code){
		String hql = "from StdDrugInfo t where t.drugCode='" + code + "'";
		return (StdDrugInfo) dao.getUniqueResult(hql);
	}

	public StdDruginfoDetail getDrugInfoDetail(String id) {
		StdDruginfoDetail data = (StdDruginfoDetail) getSession().get(
				StdDruginfoDetail.class, id);
		return data;
	}

	private DicDrugform getDrugForm(String formid) {
		DicDrugform data = (DicDrugform) getSession().get(DicDrugform.class,
				formid);
		return data;
	}

	private DicDrugspec getDrugSpec(String specid) {
		DicDrugspec data = (DicDrugspec) getSession().get(DicDrugspec.class,
				specid);
		return data;
	}

	private StdCompinfo getStdCompinfo(String compid) {
		StdCompinfo data = (StdCompinfo) getSession().get(StdCompinfo.class,
				compid);
		return data;
	}

	private DicDrugmaterial getDicDrugmaterial(String mid) {
		DicDrugmaterial data = (DicDrugmaterial) getSession().get(
				DicDrugmaterial.class, mid);
		return data;
	}

	private void writeLog(StdDrugInfo druginfo, StdDruginfoDetail infoDetail) {
		StdDruginfoLog log = new StdDruginfoLog();
		log.setLogId(UUID.randomUUID().toString());
		BeanUtils.copyProperties(druginfo, log);
		StdDruginfoDetailLog logDeatial = new StdDruginfoDetailLog();
		logDeatial.setLogId(log.getLogId());
		log.setUpdDatetime(new Date());
		BeanUtils.copyProperties(infoDetail, logDeatial);
		getSession().save(log);
		getSession().save(logDeatial);
		getSession().flush();
	}

	public StdDruginfoLog getLogInfo(String logid) {
		StdDruginfoLog data = (StdDruginfoLog) getSession().get(
				StdDruginfoLog.class, logid);
		return data;

	}
	/**
	 * 
	 *@category 取日志的上一条修改信息
	 *@author qiulei
	 *@date 2015年6月9日 下午2:01:35
	 *@param logid
	 *@param date
	 *@return
	 *@return StdDruginfoLog
	 */
	public StdDruginfoLog getPreviousLog(String drugId,String date){
		StringBuffer hql = new StringBuffer()
		.append("from StdDruginfoLog t where t.drugId=:drugId")
		.append(" and t.updDatetime < :updDatetime");
		Query query = getSession().createQuery(hql.toString());
		query.setString("drugId", drugId);
		query.setString("updDatetime",date);
		List list = query.list();
		StdDruginfoLog data = new StdDruginfoLog();
		if (null != list && list.size() > 0){
			data = (StdDruginfoLog)list.get(0);
		}
		return data;
	}

	public StdDruginfoDetailLog getLogInfoDetail(String logid) {
		StdDruginfoDetailLog data = (StdDruginfoDetailLog) getSession().get(
				StdDruginfoDetailLog.class, logid);
		return data;
	}
	
	public Pagination getDrugInfoLogList(Pagination page){
		Criteria criteria = getSession().createCriteria(StdDruginfoLog.class);
		Map<String, String> conditions = page.getConditions();
		if (null != conditions && conditions.size() > 0) {
			if (null != conditions.get("drugId")
					&& !"".equals(conditions.get("drugId").trim())) {
				criteria.add(Restrictions.eq("drugId",
						conditions.get("drugId").trim()));
			}
			if (null != conditions.get("startTime")
					&& !"".equals(conditions.get("startTime").trim())) {
				criteria.add(Restrictions.ge("updDatetime",
						ParseDate.fromFullFormat(conditions.get("startTime").trim())));
			}
			if (null != conditions.get("endTime")
					&& !"".equals(conditions.get("endTime").trim())) {
				criteria.add(Restrictions.le("updDatetime",
						ParseDate.fromFullFormat(conditions.get("endTime").trim())));
			}
		}
		criteria.addOrder(Order.desc("updDatetime"));  
		Long totalCount = (Long) criteria.setProjection(Projections.rowCount())
				.uniqueResult();
		criteria.setProjection(null);
		criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		criteria.setFirstResult(page.getFirstResult());
		criteria.setMaxResults(page.getMaxResults());
		List<StdDruginfoLog> records = criteria.list();
		page.setRecords(totalCount);
		page.setRows(records);
		return page;
	}
	/**
	 * 
	 *@category 获取被合并药品信息
	 *@author qiulei
	 *@date 2015年6月9日 下午2:52:59
	 *@param drugId
	 *@return
	 */
	public StdDrugInfo getMergeDrugInfo(String drugId){
		StdDrugInfo data = getDrugInfo(drugId);
		return data;
	}
	/**
	 * 
	 *@category 获取状态启用，并且排除被合并的列表
	 *@author qiulei
	 *@date 2015年6月9日 下午3:18:57
	 *@param page
	 *@return
	 */
	public Pagination getValidDrugInfoList (Pagination page){
		StringBuffer hql = new StringBuffer()
		.append("from StdDrugInfo t where t.status=:status")
		.append(" and t.drugId != :drugId");
		Map<String, String> conditions = page.getConditions();
		if (null != conditions && conditions.size() > 0){
			if (null != conditions.get("drugCode") && !"".equals(conditions.get("drugCode"))){
				hql.append(" and t.drugCode=:drugCode");
			}
			if (null != conditions.get("drugName") && !"".equals(conditions.get("drugName"))){
				hql.append(" and t.drugName like :drugName");
			}
//			if (null != conditions.get("drugform1") && !"".equals(conditions.get("drugform1"))){
//				hql.append(" and t.drugName like :drugName");
//			}
			if (null != conditions.get("prodPompName") && !"".equals(conditions.get("prodPompName"))){
				hql.append(" and t.compinfo.compName like :compName");
			}
		}
		Query query = getSession().createQuery("select count(*) "+hql.toString());
		query.setShort("status", Short.valueOf("1"));
		query.setString("drugId", page.getConditions().get("drugId"));
		if (null != conditions && conditions.size() > 0){
			if (null != conditions.get("drugCode") && !"".equals(conditions.get("drugCode"))){
				query.setString("drugCode", conditions.get("drugCode"));
			}
			if (null != conditions.get("drugName") && !"".equals(conditions.get("drugName"))){
				query.setString("drugName", conditions.get("drugName"));
			}
//			if (null != conditions.get("drugform1") && !"".equals(conditions.get("drugform1"))){
//				hql.append(" and t.drugName like :drugName");
//			}
			if (null != conditions.get("prodPompName") && !"".equals(conditions.get("prodPompName"))){
				query.setString("compName", conditions.get("prodPompName"));
			}
		}
		
		Long recodes = (Long)query.uniqueResult();
		page.setRecords(recodes);
		query = getSession().createQuery(hql.toString());
		query.setShort("status", Short.valueOf("1"));
		query.setString("drugId", page.getConditions().get("drugId"));
		if (null != conditions && conditions.size() > 0){
			if (null != conditions.get("drugCode") && !"".equals(conditions.get("drugCode"))){
				query.setString("drugCode", conditions.get("drugCode"));
			}
			if (null != conditions.get("drugName") && !"".equals(conditions.get("drugName"))){
				query.setString("drugName", conditions.get("drugName"));
			}
//			if (null != conditions.get("drugform1") && !"".equals(conditions.get("drugform1"))){
//				hql.append(" and t.drugName like :drugName");
//			}
			if (null != conditions.get("prodPompName") && !"".equals(conditions.get("prodPompName"))){
				query.setString("compName", conditions.get("prodPompName"));
			}
		}
		query.setFirstResult(page.getFirstResult());
		query.setMaxResults(page.getMaxResults());
		List list = query.list();
		page.setRows(list);
		return page;
	}
	/**
	 * 
	 *@category 合并药品操作
	 *@author qiulei
	 *@date 2015年6月9日 下午4:15:28
	 *@param drugOId
	 *@param drugId
	 *@return
	 */
	public String drugInfoMerge(String drugOId,String drugId){
		StdDrugInfo odata = getDrugInfo(drugOId);
		StdDrugInfo data = getDrugInfo(drugId);
		odata.setStatus(Short.valueOf("3"));
		odata.setUpdDatetime(new Date());
		odata.setHistoryDrugCode(data.getDrugCode());
		odata.setMergeStatus(Short.valueOf("0"));
		try {
			getSession().update(odata);
			getSession().flush();
			return "success";
		} catch (Exception e) {
			e.printStackTrace();
			return "failed";
		}
	}
	
	public DicSys getDicSys(String typecode,String value){
		String hql = "from DicSys t where t.classifyCode=:classifyCode and t.dicCode=:dicCode";
		Query query = getSession().createQuery(hql);
		query.setString("classifyCode", typecode);
		query.setString("dicCode", value);
		List<DicSys> list = query.list();
		if (null != list && list.size() >0){
			DicSys data = list.get(0);
			return data;
		}
		return null;
	}

}
